<template>
	<div style="width: 80%; margin: 20px auto; min-height: 600px">
		<div class="card" style="padding: 0">
			<div style="padding: 20px">
				<div style="margin-bottom: 5px;">
					<el-input v-model="data.userName" placeholder="请输入用户名称查询" style="width: 240px"></el-input>
					<el-button type="info" plain style="margin-left: 10px" @click="load">查询</el-button>
					<el-button type="warning" plain style="margin-left: 10px" @click="reset">重置</el-button>
				</div>
				<div style="margin: 20px auto;">
					<el-table :data="data.tableData" stripe @selection-change="handleSelectionChange">
						<el-table-column prop="userName" label="发送者用户名称"></el-table-column>
						<el-table-column prop="receiverName" label="接收者名称"></el-table-column>
						<el-table-column prop="transferStationName" label="接受者中转站名称"></el-table-column>
						<el-table-column label="文件">
							<template v-slot="scope">
								<template v-if="scope.row.file.toLowerCase().endsWith('blob')">
									<a style="color: blue; cursor: pointer" type="primary"
										@click="downloadFile(scope.row)">下载</a>
								</template>

								<template v-if="!scope.row.file.toLowerCase().endsWith('blob')">
									
									<a style="color: blue; cursor: pointer" type="primary" :href='scope.row.file'>下载</a>
								</template>
							</template>
						</el-table-column>
						<el-table-column prop="currentSize" label="文件大小"></el-table-column>
						<el-table-column prop="createTime" label="发送时间"></el-table-column>
						<el-table-column prop="isRead" label="是否已看"></el-table-column>
						<el-table-column label="操作" width="100" fixed="right">
							<template v-slot="scope">
								<el-button type="danger" circle :icon="Delete" @click="del(scope.row.id)"></el-button>
							</template>
						</el-table-column>
					</el-table>

				</div>
				<div v-if="data.total">
					<el-pagination @current-change="load" background layout="total, prev, pager, next"
						:page-size="data.pageSize" v-model:current-page="data.pageNum" :total="data.total" />
				</div>
			</div>

		</div>

	</div>
</template>

<script setup>
	import {
		reactive
	} from "vue";
	import request from "@/utils/request";
	import {
		ElMessage,
		ElMessageBox
	} from "element-plus";
	import {
		Delete
	} from "@element-plus/icons-vue";
	import CryptoJS from 'crypto-js';
	import JSEncrypt from 'jsencrypt';

	const baseUrl = import.meta.env.VITE_BASE_URL;
	const data = reactive({
		user: JSON.parse(localStorage.getItem('xm-user') || '{}'),
		tableData: [],
		total: 0,
		pageNum: 1, // 当前的页码
		pageSize: 5, // 每页的个数
		formVisible: false,
		form: {},
		ids: [],
		userName: null,
		userList: [],
		transferList: [],
	});

	// 加载表格数据
	const load = () => {
		request.get('/shareFile/selectPage', {
			params: {
				pageNum: data.pageNum,
				pageSize: data.pageSize,
				userName: data.userName,
				receiverId: data.user.id
			}
		}).then(res => {
			data.tableData = res.data?.list || [];
			data.total = res.data?.total;
		});
	};

	// 删除单条记录
	const del = (id) => {
		ElMessageBox.confirm('删除后数据无法恢复，您确定删除吗?', '删除确认', {
			type: 'warning'
		}).then(res => {
			request.delete(`/shareFile/delete/${id}`).then(res => {
				if (res.code === '200') {
					ElMessage.success('删除成功');
					load();
				} else {
					ElMessage.error(res.msg);
				}
			});
		}).catch(err => {
			console.error(err);
		});
	};

	// 批量删除
	const handleSelectionChange = (rows) => {
		data.ids = rows.map(v => v.id);
	};

	const delBatch = () => {
		if (!data.ids.length) {
			ElMessage.warning("请选择数据");
			return;
		}
		ElMessageBox.confirm('删除后数据无法恢复，您确定删除吗?', '删除确认', {
			type: 'warning'
		}).then(res => {
			request.delete('/shareFile/delete/batch', {
				data: data.ids
			}).then(res => {
				if (res.code === '200') {
					ElMessage.success('操作成功');
					load(); // 刷新表格数据
				} else {
					ElMessage.error(res.msg);
				}
			});
		}).catch(err => console.log(err));
	};

	const reset = () => {
		data.userName = null;
		load();
	};

	// 把所有这个用户为接收的都更新为已读
	const getFileRead = () => {
		request.get('/shareFile/getFileRead').then(res => {
			if (res.code === '200') {
				// 处理已读逻辑
			} else {
				ElMessage.error(res.msg);
			}
		});
	};

	getFileRead();
	load();

	// 获取私钥
	const getUserPrivateKey = async () => {
		try {
			console.log("当前userId: " + data.user.id);
			const uid = data.user.id;
			const response = await request.get(`/user/selectById/${uid}`);
			if (response.code === '200') {
				console.log("获取到的私钥: " + response.data.privateKey);
				return response.data.privateKey;
			} else {
				throw new Error(response.msg);
			}
		} catch (error) {
			console.error('获取私钥时出错:', error);
			ElMessage.error('获取私钥时出错，请稍后再试');
			return null;
		}
	};

	// 下载文件并解密
	const downloadFile = async (row) => {

		if (row.file.slice(-4) === '1') {

		} else {

			try {
				// 提取文件 ID
				const fileId = new URL(row.file).pathname.split('/').pop();
				// 获取加密文件
				const fileResponse = await fetch(`${baseUrl}/files/download/${fileId}`, {
					headers: {
						token: data.user.token,
					},
				});

				if (!fileResponse.ok) {
					throw new Error('文件下载失败');
				}

				const encryptedFileArrayBuffer = await fileResponse.arrayBuffer();
				const encryptedFileWordArray = CryptoJS.lib.WordArray.create(new Uint8Array(
					encryptedFileArrayBuffer));

				// 获取 AES 密钥和 IV
				const aesKeyBase64 = row.aesKey;
				const ivBase64 = row.iv;
				console.log("密钥是：" + aesKeyBase64);
				console.log("ivBase64是：" + ivBase64);

				// 使用私钥解密 AES 密钥
				const privateKey = await getUserPrivateKey();
				if (!privateKey) {
					throw new Error('私钥未找到');
				}

				const jsencrypt = new JSEncrypt();
				jsencrypt.setPrivateKey(privateKey);
				const decryptedAesKeyBase64 = jsencrypt.decrypt(aesKeyBase64);
				console.log("AES密钥解密结果：" + decryptedAesKeyBase64);
				if (!decryptedAesKeyBase64) {
					throw new Error('AES 密钥解密失败');
				}

				// 将 Base64 字符串转换为 WordArray
				const aesKey = CryptoJS.enc.Base64.parse(decryptedAesKeyBase64);
				const iv = CryptoJS.enc.Base64.parse(ivBase64);

				// 使用 AES 解密文件
				const decrypted = CryptoJS.AES.decrypt({
					ciphertext: encryptedFileWordArray
				}, aesKey, {
					iv: iv,
					mode: CryptoJS.mode.CBC,
					padding: CryptoJS.pad.Pkcs7,
				});
				console.log("使用 AES 解密文件");

				// 将解密后的 WordArray 转换为 ArrayBuffer
				const decryptedWords = decrypted.words;
				const decryptedBytes = [];
				for (let i = 0; i < decryptedWords.length; i++) {
					const hex = (decryptedWords[i] >>> 0).toString(16).padStart(8, '0');
					decryptedBytes.push(...hex.match(/.{1,2}/g).map(byte => parseInt(byte, 16)));
				}
				const decryptedArrayBuffer = new Uint8Array(decryptedBytes).buffer;
				console.log("decryptedArrayBuffer:", decryptedArrayBuffer);

				// 创建 Blob 对象
				const blob = new Blob([decryptedArrayBuffer], {
					type: row.fileType || 'application/octet-stream'
				}); // 假设 fileType 是文件类型
				console.log("创建 Blob 对象成功");
				console.log("文件类型:", row.fileType);

				// 验证文件头（以 JPEG 文件为例）
				if (row.fileType && row.fileType.includes('image/jpeg')) {
					console.log("验证 JPEG 文件头开始");
					const jpegHeader = [0xFF, 0xD8];
					const slice = blob.slice(0, 2);
					console.log("slice:", slice);
					if (slice.size !== 2) {
						throw new Error('Blob 切片大小不正确');
					}
					const arrayBuffer = await slice.arrayBuffer();
					console.log("arrayBuffer:", arrayBuffer);
					const view = new DataView(arrayBuffer);
					console.log("view:", view);
					const headerByte1 = view.getUint8(0);
					const headerByte2 = view.getUint8(1);
					console.log("headerByte1:", headerByte1);
					console.log("headerByte2:", headerByte2);
					if (headerByte1 !== jpegHeader[0] || headerByte2 !== jpegHeader[1]) {
						throw new Error('JPEG 文件头验证失败，文件可能损坏');
					}
					console.log("JPEG 文件头验证成功");
				} else if (row.fileType && row.fileType.includes('application/pdf')) {
					console.log("验证 PDF 文件头开始");
					const pdfHeader = [0x25, 0x50, 0x44, 0x46, 0x2D];
					const slice = blob.slice(0, 5);
					console.log("slice:", slice);
					if (slice.size !== 5) {
						throw new Error('Blob 切片大小不正确');
					}
					const arrayBuffer = await slice.arrayBuffer();
					console.log("arrayBuffer:", arrayBuffer);
					const view = new DataView(arrayBuffer);
					console.log("view:", view);
					const headerByte1 = view.getUint8(0);
					const headerByte2 = view.getUint8(1);
					const headerByte3 = view.getUint8(2);
					const headerByte4 = view.getUint8(3);
					const headerByte5 = view.getUint8(4);

					if (
						headerByte1 !== pdfHeader[0] ||
						headerByte2 !== pdfHeader[1] ||
						headerByte3 !== pdfHeader[2] ||
						headerByte4 !== pdfHeader[3] ||
						headerByte5 !== pdfHeader[4]
					) {
						throw new Error('PDF 文件头验证失败，文件可能损坏');
					}
					console.log("PDF 文件头验证成功");
				} else if (row.fileType && row.fileType.includes('text/plain')) {
					// txt 文件没有固定的二进制文件头，但我们可以检查文件扩展名
					if (!row.fileName.endsWith('.txt')) {
						isValidFile = false;
						throw new Error('TXT 文件扩展名验证失败');
					}
					console.log("跳过 TXT 文件头验证");
				} else if (row.fileType && row.fileType.includes(
						'application/vnd.openxmlformats-officedocument.wordprocessingml.document')) {
					console.log("验证 DOCX 文件头开始");
					const docxHeader = [0x50, 0x4B, 0x03, 0x04];
					const slice = blob.slice(0, 4);
					console.log("slice:", slice);
					if (slice.size !== 4) {
						throw new Error('Blob 切片大小不正确');
					}
					const arrayBuffer = await slice.arrayBuffer();
					console.log("arrayBuffer:", arrayBuffer);
					const view = new DataView(arrayBuffer);
					console.log("view:", view);
					const headerByte1 = view.getUint8(0);
					const headerByte2 = view.getUint8(1);
					const headerByte3 = view.getUint8(2);
					const headerByte4 = view.getUint8(3);

					if (
						headerByte1 !== docxHeader[0] ||
						headerByte2 !== docxHeader[1] ||
						headerByte3 !== docxHeader[2] ||
						headerByte4 !== docxHeader[3]
					) {
						isValidFile = false;
						throw new Error('DOCX 文件头验证失败，文件可能损坏');
					}
					console.log("DOCX 文件头验证成功");
				} else {
					console.log("跳过文件头验证");
				}

				// 创建下载链接
				const url = window.URL.createObjectURL(blob);
				const a = document.createElement('a');
				a.href = url;
				a.download = row.fileName;
				document.body.appendChild(a);
				a.click();
				document.body.removeChild(a);
				window.URL.revokeObjectURL(url);
				ElMessage.success('文件下载成功');
			} catch (error) {
				console.error('下载文件时出错:', error);
				ElMessage.error('下载文件时出错，请稍后再试');
			}

		}
	};
</script>